#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

#include <sys/stat.h>
#include <fcntl.h>

//创建守护进程
//创建成功则返回-1,否则返回-1
int ngx_daemon()
{
	int fd;
	switch(fork())//fork()子进程
	{
		case -1:
			//创建子进程失败,这里可以写日志...
			return -1;
		case 0:
			//子进程,走到这里,直接break
			break;
		default:
			//父进程,直接退出
			exit(0);
	}

	//只有子进程流程才能走到这里
	if(setsid() == -1) //脱离终端,终端关闭,将跟此子进程无关
	{
		//记录日志...
		return -1;
	}
	
	umask(0);//设置为0,不要让它来限制文件限制,以免引起混乱

	fd = open("/dev/null", O_RDWR); //打开黑洞设备,以读写方式打开
	if(fd == -1)
	{
		//记录错误日志....
		return -1;
	}

	if(dup2(fd, STDIN_FILENO) == -1) //先关闭STDIN_FILENO,再重定向到黑洞
	{
		//记录错误日志...
		return -1;
	}

	if(dup2(fd, STDOUT_FILENO) == -1) //先关闭STDOUT_FILENO，再重定向到黑洞
	{
		//记录错误日志...
		return -1;
	}

	if(fd > STDERR_FILENO) //fd应该是3,这个成立
	{
		if(close(fd) == -1) //释放资源,这样这个文件描述符就可以被复用,不然这个数字【文件描述符】会被一值占用
		{
			//记录错误日志...
			return -1;
		}
	}

	return 1;
}

int main(int argc, char *const *agrv)
{
	if(ngx_daemon() != 1)
	{
		//创建守护进程失败,可以做失败后的处理比如写日志等
		return 1;
	}
	else
	{
		//创建守护进程成功,执行守护进程中要干的活
		for(;;)
		{
			sleep(1);//休息1秒
			printf("休息1秒,进程id=%d\n", getpid());//你就算打印也没用,现在的标准输出指向黑洞(/dev/null)，打印
		}
	}
	return 0;
}
